// -- status --
export const STATUS_NONE = 'none' as const;
export const STATUS_APPEAR = 'appear' as const;
export const STATUS_ENTER = 'enter' as const;
export const STATUS_LEAVE = 'leave' as const;

export type MotionStatus =
  | typeof STATUS_NONE
  | typeof STATUS_APPEAR
  | typeof STATUS_ENTER
  | typeof STATUS_LEAVE;

//-- step --
export const STEP_NONE = 'none' as const;
export const STEP_PREPARE = 'prepare' as const;
export const STEP_START = 'start' as const;
export const STEP_ACTIVE = 'active' as const;
export const STEP_ACTIVATED = 'end' as const;

export type MotionStep =
  | typeof STEP_NONE
  | typeof STEP_PREPARE
  | typeof STEP_START
  | typeof STEP_ACTIVE
  | typeof STEP_ACTIVATED;

export type MotionName =
  | string
  | {
      appear?: string;
      enter?: string;
      leave?: string;
      appearActive?: string;
      enterActive?: string;
      leaveActive?: string;
    };

export type MotionEvent = TransitionEvent | AnimationEvent;

export type MotionPrepareEventHandler = (
  element: HTMLElement,
) => Promise<any> | void;

export type MotionEventHandler = (
  element: HTMLElement,
) => React.CSSProperties | void;

export type MotionEndEventHandler = (
  element: HTMLElement,
  event: MotionEvent,
) => void;

export type MotionChildrenFirstProps<ListItem = any> = {
  visible?: boolean;
  className?: string;
  style?: React.CSSProperties;
  listItem?: ListItem;
  [property: string]: any;
};

export interface YmCssMotionProps<ListItem = any> {
  visible: boolean;
  motionName: string;
  motionAppear?: boolean;
  motionEnter?: boolean;
  motionLeave?: boolean;
  forceRender?: boolean;
  removeOnLeave?: boolean;
  leavedClassName?: string;

  onAppearPrepare?: MotionPrepareEventHandler;
  onEnterPrepare?: MotionPrepareEventHandler;
  onLeavePrepare?: MotionPrepareEventHandler;

  onAppearStart?: MotionEventHandler;
  onEnterStart?: MotionEventHandler;
  onLeaveStart?: MotionEventHandler;

  onAppearActive?: MotionEventHandler;
  onEnterActive?: MotionEventHandler;
  onLeaveActive?: MotionEventHandler;

  onAppearEnd?: MotionEndEventHandler;
  onEnterEnd?: MotionEndEventHandler;
  onLeaveEnd?: MotionEndEventHandler;

  childrenFnParams?: { listItem?: ListItem; [property: string]: any };
  children: (
    props: MotionChildrenFirstProps<ListItem>,
    ref: (node: HTMLElement) => void,
  ) => React.ReactElement;
  onVisibleChanged?: (visible: boolean, info?: ListItem) => void;
}

interface ComponentProps extends Omit<React.HTMLAttributes<any>, 'children'> {
  tagName: string;
}

export interface YmCssMotionListProps<ListItem = any>
  extends Omit<YmCssMotionProps<ListItem>, 'visible'> {
  componentProps?: ComponentProps;
  rowKey: string;
  dataSource: ListItem[];
  onAllRemoved?: () => void;
}
